using System.Windows.Media.Imaging;
using AndyPike.Experiments.Fluent.Interfaces;

namespace AndyPike.Experiments.Fluent.Commands
{
    public class ContrastCommand : ICommand
    {
        private readonly double contrastFactor;

        public ContrastCommand(int level)
        {
            GuardAgainst.ArgumentOutsideRange(level, "level", -100, 100);

            contrastFactor = (100.0 + level) / 100.0;
            contrastFactor *= contrastFactor;
        }

        public WriteableBitmap Execute(WriteableBitmap image)
        {
            GuardAgainst.ArgumentNull(image, "image");

            var info = new ImageInfo(image);
            var pixels = new byte[info.TotalBytes];
            image.CopyPixels(pixels, info.Stride, 0);

            for (var x = 0; x < info.TotalBytes; ++x)
            {
                if ((x + 1) % info.BytesPerPixel != 0)
                {
                    var newValue = pixels[x]/255.0;
                    newValue -= 0.5;
                    newValue *= contrastFactor;
                    newValue += 0.5;
                    newValue *= 255;

                    if (newValue > 255)
                        newValue = 255;
                    if (newValue < 0)
                        newValue = 0;

                    pixels[x] = (byte) newValue;
                }
            }

            image.WritePixels(info.Rect, pixels, info.Stride, 0);

            return image;
        }
    }
}